package com.tjc.media.service;
import com.alibaba.fastjson2.JSON;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.exception.CosClientException;
import com.qcloud.cos.exception.CosServiceException;
import com.qcloud.cos.model.*;
import com.qcloud.cos.transfer.TransferManager;
import com.qcloud.cos.transfer.TransferManagerConfiguration;
import com.qcloud.cos.transfer.Upload;
import com.ruoyi.common.config.TencentCosConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Component
public class TencentCosService {

    private static final Logger log = LoggerFactory.getLogger(TencentCosService.class);

    @Autowired
    private COSClient cosClient;

    @Resource
    private TencentCosConfig tencentCosConfig;

    private TransferManager transferManager;
    /**
     * 初始化传输管理器（用于大文件上传）
     */
    public void initTransferManager() {
        ExecutorService threadPool = Executors.newFixedThreadPool(10);
        TransferManagerConfiguration transferManagerConfiguration = new TransferManagerConfiguration();
        transferManagerConfiguration.setMultipartUploadThreshold(5 * 1024 * 1024); // 5MB
        transferManagerConfiguration.setMinimumUploadPartSize(1 * 1024 * 1024); // 1MB

        transferManager = new TransferManager(cosClient, threadPool);
        transferManager.setConfiguration(transferManagerConfiguration);
    }

    /**
     * 上传文件（本地文件）
     */
    public String uploadFile(File localFile, String key) {
        try {
            PutObjectRequest putObjectRequest = new PutObjectRequest(tencentCosConfig.getBucketName(), key, localFile);
            PutObjectResult putObjectResult = cosClient.putObject(putObjectRequest);
            return tencentCosConfig.getDomain() + "/" + key;
        } catch (CosServiceException e) {
            // 服务端异常
            throw new RuntimeException("COS服务异常: " + e.getErrorMessage(), e);
        } catch (CosClientException e) {
            // 客户端异常
            throw new RuntimeException("COS客户端异常", e);
        }
    }

    /**
     * 上传文件（MultipartFile）
     */
    public String uploadFile(MultipartFile file, String key) {
        try (InputStream inputStream = file.getInputStream()) {
            /*boolean doesObjectExist = this.doesObjectExist(tencentCosConfig.getBucketName(), key);
            if(doesObjectExist) {
                this.deleteFile(key);
            }*/
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setContentLength(file.getSize());
            metadata.setContentType(file.getContentType());
            PutObjectRequest putObjectRequest = new PutObjectRequest(tencentCosConfig.getBucketName(), key, inputStream, metadata);
            PutObjectResult putObjectResult = cosClient.putObject(putObjectRequest);
            String path = tencentCosConfig.getDomain();
            if(!key.startsWith("/")) {
                path += "/";
            }
            path += key;
            log.info("文件上传成功,返回结果：{}，文件路径：{}", JSON.toJSONString(putObjectResult), path);
            return path;
        } catch (IOException e) {
            throw new RuntimeException("文件读取失败", e);
        } catch (CosServiceException e) {
            throw new RuntimeException("COS服务异常: " + e.getErrorMessage(), e);
        } catch (CosClientException e) {
            throw new RuntimeException("COS客户端异常", e);
        }
    }

    /**
     * 检查文件是否存在
     * @param bucketName 存储桶名称
     * @param key 文件在COS中的路径
     * @return true-存在, false-不存在
     */
    public boolean doesObjectExist(String bucketName, String key) {
        try {
            ObjectMetadata metadata = cosClient.getObjectMetadata(bucketName, key);
            return metadata != null;
        } catch (Exception e) {
            log.info(e.getMessage());
            // 文件不存在时会抛出异常
            return false;
        }
    }

    /**
     * 上传文件并生成唯一文件名
     */
    public String uploadFileWithUniqueName(MultipartFile file, String directory) {
        String originalFilename = file.getOriginalFilename();
        String fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
        String uniqueFileName = UUID.randomUUID().toString() + fileExtension;
        String key = directory + "/" + uniqueFileName;

        return uploadFile(file, key);
    }

    /**
     * 大文件分片上传
     */
    public String uploadBigFile(File localFile, String key) {
        if (transferManager == null) {
            initTransferManager();
        }

        try {
            PutObjectRequest putObjectRequest = new PutObjectRequest(tencentCosConfig.getBucketName(), key, localFile);
            Upload upload = transferManager.upload(putObjectRequest);
            upload.waitForUploadResult();
            return tencentCosConfig.getDomain() + "/" + key;
        } catch (CosServiceException e) {
            throw new RuntimeException("COS服务异常: " + e.getErrorMessage(), e);
        } catch (CosClientException e) {
            throw new RuntimeException("COS客户端异常", e);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new RuntimeException("上传被中断", e);
        }
    }

    /**
     * 下载文件
     */
    public void downloadFile(String key, File downloadFile) {
        try {
            GetObjectRequest getObjectRequest = new GetObjectRequest(tencentCosConfig.getBucketName(), key);
            cosClient.getObject(getObjectRequest, downloadFile);
        } catch (CosServiceException e) {
            throw new RuntimeException("COS服务异常: " + e.getErrorMessage(), e);
        } catch (CosClientException e) {
            throw new RuntimeException("COS客户端异常", e);
        }
    }

    /**
     * 删除文件
     */
    public void deleteFile(String key) {
        try {
            cosClient.deleteObject(tencentCosConfig.getBucketName(), key);
        } catch (CosServiceException e) {
            throw new RuntimeException("COS服务异常: " + e.getErrorMessage(), e);
        } catch (CosClientException e) {
            throw new RuntimeException("COS客户端异常", e);
        }
    }

    /**
     * 批量删除文件
     */
    public void deleteFiles(List<String> keys) {
        try {
            DeleteObjectsRequest deleteObjectsRequest = new DeleteObjectsRequest(tencentCosConfig.getBucketName());

            List<DeleteObjectsRequest.KeyVersion> keyList = new ArrayList<>();
            for (String key : keys) {
                keyList.add(new DeleteObjectsRequest.KeyVersion(key));
            }

            deleteObjectsRequest.setKeys(keyList);
            cosClient.deleteObjects(deleteObjectsRequest);
        } catch (CosServiceException e) {
            throw new RuntimeException("COS服务异常: " + e.getErrorMessage(), e);
        } catch (CosClientException e) {
            throw new RuntimeException("COS客户端异常", e);
        }
    }

    /**
     * 获取文件列表
     */
    public List<COSObjectSummary> listFiles(String prefix) {
        try {
            ListObjectsRequest listObjectsRequest = new ListObjectsRequest();
            listObjectsRequest.setBucketName(tencentCosConfig.getBucketName());
            listObjectsRequest.setPrefix(prefix);
            listObjectsRequest.setMaxKeys(1000);

            ObjectListing objectListing = cosClient.listObjects(listObjectsRequest);
            return objectListing.getObjectSummaries();
        } catch (CosServiceException e) {
            throw new RuntimeException("COS服务异常: " + e.getErrorMessage(), e);
        } catch (CosClientException e) {
            throw new RuntimeException("COS客户端异常", e);
        }
    }

    /**
     * 获取文件信息
     */
    public ObjectMetadata getFileInfo(String key) {
        try {
            return cosClient.getObjectMetadata(tencentCosConfig.getBucketName(), key);
        } catch (CosServiceException e) {
            throw new RuntimeException("COS服务异常: " + e.getErrorMessage(), e);
        } catch (CosClientException e) {
            throw new RuntimeException("COS客户端异常", e);
        }
    }

    /**
     * 关闭客户端
     */
    public void shutdown() {
        if (cosClient != null) {
            cosClient.shutdown();
        }
        if (transferManager != null) {
            transferManager.shutdownNow();
        }
    }
}
